<h1>Web API Documentation</h1>

<p>
The web API is based entirely on JSON POST requests. The requests are sent to
<i>/ajax</i> and contain the data formatted as JSON object in the body of the
POST request.
</p>

<p>
The JSON object sent to the application must contain two fields:
<ul>
    <li><i>userId</i>: the facebook ID of the user</li>
    <li><i>data</i>: a JSON array where each element contains a request</li>
</ul>
The <i>Content-Type</i> of the JSON request should be <i>application/json;charset=utf-8</i>.
</p>

<p>
Each entry of <i>data</i> is a separate request, but they are all performed
within the same SQL session, so an SQL error in one request causes the entire
session to rollback.
</p>

<p>
Each request entry in <i>data</i> must contain a <i>controller</i> field and a
<i>method</i> field. Those two fields will determine which method in which
class in ilender.controller will handle that request entry. The rest of the
fields will be sent as the <i>request</i> argument to that method.
</p>

<p>
If one of the controller methods called during the request throws an exception,
the server returns a JSON object with an <i>errors</i> field which contains an
array of errors - the first one is the original exception, the second is it's
cause and so on. Each entry of this array is an object containing <i>error</i>
- a string containing the error message - and <i>stackTrace</i> - an array
containing the stack trace.
</p>

<p>
Otherwise, the server returns a JSON array containing an entry for each request
object sent. That does not meaning everything went smoothly - it is still
possible that one of the controller methods failed and even failed the entire
session - but it returned it's error individually without throwing an exception
to the dispatcher.
</p>

<p>
<i>ilender.dispatching.AjaxServlet</i> handles this mechanism on the server
side. On the client side, <i>app/js_manual_load/dispatching.js</i> contains
functions that help sending messages to the server in this format.
</p>

<p>
See the Javadoc for the ilender.controller package to find out what each
controller and each method does. To generate the Javadoc, use <i>and doc</i>.
This will generate the Javadoc to the <i>javadoc</i> folder.
</p>

<h2>Example</h2>

<p>
Let's look at the <i>search</i> method of <i>ItemsController</i>. It's request
format is:<pre>
{
    form_data:{
        search_string:(the search string)
    }
}
</pre>
and it's response format is:<pre>
{
    entries:[
        (item cardlet),
        ...
    ]
}
</pre>

So, let's say we want to borrow some learning material. We enter "learning" the
the <b>Borrow</b> searchbox, and click on <b>Search</b>. This sends the
following JSON request:<pre>
{
    "userId":1157572342,
    "request":[
        {
            "controller":"items",
            "method":"search",
            "params":{
                "form_data":{
                    "search_string":"learning"
                }
            }
        }
    ]
}
</pre>
</p>

<p>
<i>userId</i> is 1157572342 because that's my user id. <i>request</i> is the
array of requests - we only have one, but there can be multiple. This request
is sent to the <i>search</i> method in the <i>items</i> controller, and it's
<i>params</i> object is organized like specified in the javadoc - it has a
single field named <i>search_string</i> that has the search string we entered -
"learning". This object is what the controller method will receive as argument.
</p>

<p>
The web API returns the following JSON response:<pre>
[
    {
        "entries":[
            {
                "facebook_user_id":100000058327952,
                "category":{
                    "name":"Textbooks",
                    "id":4
                },
                "name":"Infi 2 workbook",
                "description":"for student of Math Dep",
                "tags":["learning", "books"],
                "id":19,
                "ejs":"cardlet/item",
                "facebook_user_name":"Jen Sanko"
            },
            {
                "facebook_user_id":100000724910234,
                "category":{
                    "name":"Textbooks",
                    "id":4
                },
                "name":"Infi 2 workbook",
                "description":"for student of Math Dep",
                "tags":["learning", "books"],
                "id":14,
                "ejs":"cardlet/item",
                "facebook_user_name":"Leon Berzak"
            }
        ]
    }
]
</pre>
The type of object returned is a list - because we can send mutliple requests,
which means we could have gotten multiple responses - but we only send a single
request so the list has a single entry. This entry is the response object for
our request, and like specified in the javadoc - it contains a single field
named <i>entries</i>. This field is a list with one entry for each result. That
entry is an object containing all details required required for creating a
cradlet - so the javascript code <i>renderEjs(entry)</i> will return the
cardlet HTML for that entry, and the javascript code
<i>renderEjs('cardlet/cardlet_list',response)</i> will return a cardlet list of
all the results we got.
</p>
